﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace LitTools
{
    /// <summary>
    /// 消息管理单例
    /// </summary>
    public class MessageManager : MonoSingleton<MessageManager>
    {
        public bool openLog = true;
        public delegate bool MessageAct(IMessageObj message);//消息委托
        private Dictionary<string, List<MessageAct>> receiverDict;//接收者字典
        private List<IMessageObj> messageList;//消息字典
        public override void Init()
        {
            base.Init();
            messageList = new List<IMessageObj>();
            receiverDict = new Dictionary<string, List<MessageAct>>();
        }

        public void BoradcastMessage<T>(T message, bool sync = false) where T : IMessageObj
        {
            if (!receiverDict.ContainsKey(message.MessageId)) return;
            if (sync)
            {
                //同步处理
                //移除已经添加到列表中的消息
                for (int i = 0; i < messageList.Count; i++)
                {
                    if (messageList[i].MessageId.Equals(message.MessageId))
                    {
                        Log("Sync Remove Message");
                        messageList.RemoveAt(i);
                        i--;
                    }
                }
                //立即调用接收者委托
                for (int i = 0; i < receiverDict[message.MessageId].Count; i++)
                {
                    var remove = receiverDict[message.MessageId][i].Invoke(message);
                    if (!remove)
                    {
                        receiverDict[message.MessageId].RemoveAt(i);
                        i--;
                    }
                }
            }
            else
            {
                //异步处理
                //添加到队列中
                for (int i = 0; i < messageList.Count; i++)
                {
                    //如果之前有同类消息缓存，覆盖之
                    if (messageList[i].MessageId.Equals(message.MessageId))
                    {
                        messageList[i] = message;
                        return;
                    }
                }
                messageList.Add(message);
            }
        }

        private void Update()
        {
            if (messageList.Count <= 0) return;
            for (int i = 0; i < messageList.Count; i++)
            {
                var message = messageList[i];
                for (int j = 0; j < receiverDict[message.MessageId].Count; j++)
                {
                    var remove = receiverDict[message.MessageId][j].Invoke(message);
                    if (!remove)
                    {
                        receiverDict[message.MessageId].RemoveAt(j);
                        Log("RemoveReceiver");
                        j--;
                    }
                }
            }
            messageList.Clear();
        }

        public void RegisterMessage(string messageKey, MessageAct act)
        {
            if (!receiverDict.ContainsKey(messageKey))
                receiverDict.Add(messageKey, new List<MessageAct>());
            if (!receiverDict[messageKey].Contains(act))
                receiverDict[messageKey].Add(act);
        }

        public void UnregisterMessage(string messageKey, MessageAct act)
        {
            if (!receiverDict.ContainsKey(messageKey)) return;
            if (!receiverDict[messageKey].Contains(act)) return;
            receiverDict[messageKey].Remove(act);
        }

        private void Log(string str)
        {
            if (!openLog) return;
            Debug.Log("MessageManager:" + str);
        }
    }

    public class MessageKey
    {
        /// <summary>
        /// 自己进入房间
        /// </summary>
        public const string JOINROOM_SelfPLAYER = "JOINROOM_SelfPLAYER";
        /// <summary>
        /// 他人进入房间
        /// </summary>
        public const string JOINROOM_OTHERPLAYER = "JOINROOM_OTHERPLAYER";
        /// <summary>
        /// 进入多人游戏倒计时
        /// </summary>
        public const string COUNTDONW_ENTERMULTGAME = "COUNTDONW_ENTERMULTGAME";
    }
}